package com.huluobo.a2107jetpackkotlindemo.coroutine

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.huluobo.a2107jetpackkotlindemo.R
import com.huluobo.a2107jetpackkotlindemo.databinding.ActivityCoroutineBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.lang.Exception

class CoroutineActivity : AppCompatActivity() {
    private lateinit var activityCoroutineActivity: ActivityCoroutineBinding
    val job = Job()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activityCoroutineActivity = ActivityCoroutineBinding.inflate(layoutInflater);
        setContentView(activityCoroutineActivity.root)
        //GlobalScope 全域
        //launch 发射 发出
//        val job = GlobalScope.launch(Dispatchers.IO) {
//            Log.i("TagA", "当前线程${Thread.currentThread().name}")
//        }
//        job.cancel()
//        GlobalScope.launch (Dispatchers.Main){
//            Log.i("TagA", "当前线程${Thread.currentThread().name}")
//        }

        CoroutineScope(job).launch {
//            //async 代表以下执行的代码块是异步进行的
//            //.await() 代表异步执行结果之前,需要等待
//            val result = async {
//                try {
//                    delay(3000)
//                    "运算结果:" + 3 / 0
//                } catch (e: Exception) {
//                    "结果异常"
//                }
//            }.await()
//            Log.i("TagA", result)
            val startTime = System.currentTimeMillis()
            val result = async {
                delay(2000)
                "result操作成功"
            }

            val result2 = async {
                delay(1000)
                "result2操作成功"
            }
            Log.i("TagA", "执行结果:${result.await()},${result2.await()}")
            val endTime = System.currentTimeMillis()
            Log.i("TagA", "执行时间:${endTime - startTime}")
            //出现执行了3秒的过程,因为result执行完后,会直接执行result2,会造成线程阻塞,所以时间会相加
            //程序是按照上下的顺序来执行的,当在过程中调用await时,会造成当前线程阻塞,所以是同步执行,执行的时间会相加
            //如果是在结果中调用await,这时是异步执行,时间不会相加
        }

        CoroutineScope(job).launch {
            loadData()
        }

        CoroutineScope(job).launch {
            //Dispatchers.IO 常用耗时操作,比如网络请求,文件读写等
            //Dispatchers.Main 表示程序在主线程中执行,所以在开启协程时,他的代码不一定在子线程中执行,也可以进行切换
            //Dispatchers.Default 表示用于计算密集型
            //Dispatchers.Unconfined 没有规则的,任意执行
            //withContext 通过withContext来指定当前结果处于哪一条线程中
            val result = withContext(Dispatchers.IO) {
                delay(2000)
                "操作陈宫"
            }
            Log.i("TagA", "result:$result")
        }

        loadDataFromNetwork()
    }

    //suspend 挂起(暂停)的关键字,标记当前的方法为一个挂起的方法
    //程序或者系统开发时,并不知道一个方法是否会在协程中运行,所以需要添加挂起的关键字来提示其他程序员(开发者),当前方法需要放到协程中使用
    private suspend fun loadData() {
        delay(2000)
        Log.i("TagA", "--------------loadData-----------")
    }

    private fun loadDataFromNetwork() {
//        Thread {//通过异步方法或者异步块来执行网络请求,使用主线程会进行耗时操作会报错(线程阻塞ANR)
//            //执行异步请求
//            runOnUiThread {
//                //切换到UI线程展示结果
//            }
//        }
        CoroutineScope(job).launch(Dispatchers.Main) {
            val result = withContext(Dispatchers.IO) {
                delay(2000)
                "获取网络成功"
            }
            activityCoroutineActivity.tvCenter.text = result
        }
    }
}